package in.srain.cube.views.ptr;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

import in.srain.cube.views.ptr.indicator.PtrIndicator;

/**
 * 下拉刷新的容器
 * 修改了触摸事件的分发方式,遵循系统的事件分发逻辑
 * 使得拥有更好的体验
 */
public class PtrFrameLayout2 extends PtrFrameLayout {

    private static final String TAG = "PtrFrameLayout2";
    /**
     * 是否开始拖动
     */
    protected boolean isBegin;

    /**
     * 是否正在移动中
     */
    private boolean moving;

    /**
     * 最后一次记录的位置
     */
    private float lastY = -1;
    private float lastX = -1;
    /**
     * 在关闭横向滑动时有作用
     * 是否可以滑动 = 垂直滑动距离 >= 横向滑动距离 * mHorizontalPercent
     */
    private float mHorizontalPercent = 1.2f;

    public PtrFrameLayout2(Context context) {
        super(context);
    }

    public PtrFrameLayout2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public PtrFrameLayout2(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    /**
     * 当用户移动
     *
     * @param delta
     * @param x
     * @param y
     */
    void onMove(float delta, float x, float y) {
        getmPtrIndicator().onMove(x, y);
        float offsetX = getmPtrIndicator().getOffsetX();
        float offsetY = getmPtrIndicator().getOffsetY();
        movePos(offsetY);
    }


    /**
     * 当用户手指按下
     *
     * @param x
     * @param y
     */
    void onDown(float x, float y) {
        getmPtrIndicator().onPressDown(x, y);
    }

    /**
     * 当用户松开或取消
     *
     * @param x
     * @param y
     */
    void onCancelOrUp(float x, float y) {
        getmPtrIndicator().onRelease();
        if (getmPtrIndicator().hasLeftStartPosition()) {
            onRelease(false);
        }
    }


    @Override
    protected void sendCancelEvent() {

    }

    @Override
    protected void sendDownEvent() {

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (getmPtrHandler() == null) return super.onTouchEvent(ev);
        switch (ev.getAction() & 0xFF) {
            case MotionEvent.ACTION_DOWN: {
                isBegin = true;
                moving = false;
                lastY = ev.getY();
                lastX = ev.getX();
                onDown(ev.getX(), ev.getY());
            }
            break;
            case MotionEvent.ACTION_MOVE: {
                float deltaY = ev.getY() - lastY;
                float deltaX = ev.getX() - lastX;

                if (moving) {
                    moving = true;
                    onMove(deltaY, ev.getX(), ev.getY());
                } else {
                    if (deltaY > 0 && Math.abs(deltaX) < Math.abs(deltaY)) {
                        if (isBegin && Math.abs(deltaY) >= getmPagingTouchSlop() && getmPtrHandler().checkCanDoRefresh(this, getContentView(), getHeaderView())) {
                            if (isDisableWhenHorizontalMove()) {
                                if (Math.abs(deltaX) * mHorizontalPercent < Math.abs(deltaY)) {
                                    moving = true;
                                    onMove(deltaY, ev.getX(), ev.getY());
                                }
                            } else {
                                moving = true;
                                onMove(deltaY, ev.getX(), ev.getY());
                            }
                        }
                    }
                }

            }
            break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
            }
            break;
        }

        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (getmPtrHandler() == null) return super.onInterceptTouchEvent(ev);
        if (isRefreshing()) {
            //快速关闭
            final int tmp = (int) getDurationToCloseHeader();
            setDurationToCloseHeader(100);
            refreshComplete();
            setDurationToCloseHeader(tmp);
            return super.onInterceptTouchEvent(ev);
        }

        boolean isConsumed = false;

        switch (ev.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                isBegin = true;
                moving = false;
                lastY = ev.getY();
                lastX = ev.getX();

                getmScrollChecker().abortIfWorking();
                onDown(ev.getX(), ev.getY());

                break;
            case MotionEvent.ACTION_MOVE:

                float deltaY = ev.getY() - lastY;
                float deltaX = ev.getX() - lastX;

                if (moving) {
                    moving = true;
                    isConsumed = true;
                    onMove(deltaY, ev.getX(), ev.getY());
                } else {
                    if (deltaY > 0 && Math.abs(deltaX) < Math.abs(deltaY)) {
                        if (deltaY > 0 && Math.abs(deltaX) < Math.abs(deltaY)) {
                            if (isBegin && Math.abs(deltaY) >= getmPagingTouchSlop() && getmPtrHandler().checkCanDoRefresh(this, getContentView(), getHeaderView())) {
                                if (isDisableWhenHorizontalMove()) {
                                    if (Math.abs(deltaX) * mHorizontalPercent < Math.abs(deltaY)) {
                                        moving = true;
                                        isConsumed = true;
                                        onMove(deltaY, ev.getX(), ev.getY());
                                    }
                                } else {
                                    moving = true;
                                    isConsumed = true;
                                    onMove(deltaY, ev.getX(), ev.getY());
                                }
                            }
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                break;
        }

        return isConsumed || super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                isBegin = false;
                moving = false;
                lastY = -1;
                lastX = -1;
                /**事件分发时如果没有处理后续事件九无法获取Up事件
                 那么就有一个问题,我再刷新时滚动这个内容视图,那么就会只有按下事件
                 导致 {@link PtrIndicator#isUnderTouch()} 为true
                 当调用刷新完成时判断是否已经释放({@link PtrIndicator#isUnderTouch() 为false}
                 结果是未释放,导致无法将试图推到原点
                 */
                onCancelOrUp(e.getX(), e.getY());
                break;
        }
        return dispatchTouchEventSupper(e);
    }


}
